package ph.com.gs3.formalistics.presenter;

import java.util.List;

import ph.com.gs3.formalistics.R;
import ph.com.gs3.formalistics.global.utilities.DateUtilities;
import ph.com.gs3.formalistics.model.vo.business.Comment;
import ph.com.gs3.formalistics.model.vo.business.User;
import ph.com.gs3.formalistics.presenter.fragements.workers.CommentsWorkerFragment;
import ph.com.gs3.formalistics.presenter.fragements.workers.CommentsWorkerFragment.CommentDeleteFailedException;
import ph.com.gs3.formalistics.presenter.fragments.views.CommentsViewFragment;
import ph.com.gs3.formalistics.presenter.fragments.views.CommentsViewFragment.CommentListViewActionListener;
import ph.com.gs3.formalistics.services.managers.SessionManager;
import ph.com.gs3.formalistics.services.managers.SessionManager.Mode;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.Toast;

public class CommentsActivity extends Activity implements CommentListViewActionListener {

	public static final String TAG = CommentsActivity.class.getSimpleName();
	public static final String EXTRA_CURRENT_USER = "current_user";
	public static final String EXTRA_CURRENT_DOCUMENT_ID = "document_id";

	private CommentsWorkerFragment commentsWorkerFragment;
	private CommentsViewFragment commentsViewFragment;

	private List<Comment> commentsOnDisplay;

	private User currentUser;
	private int currentDocumentId;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_comments);

		initializeWorkerFragment();
		initializeData();
		registerBroadcastReceivers();

		if (savedInstanceState == null) {
			commentsViewFragment = CommentsViewFragment.createInstance(this, commentsOnDisplay);
			getFragmentManager().beginTransaction().add(R.id.container, commentsViewFragment)
			        .commit();
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		int id = item.getItemId();
		if (id == R.id.action_delete_comment) {
			AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
			        .getMenuInfo();

			deleteComment(commentsOnDisplay.get(info.position));

			return true;
		}

		return super.onContextItemSelected(item);
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, view, menuInfo);

		AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
		int position = info.position;

		Comment selectedComment = commentsOnDisplay.get(position);

		// If the author of this comment is the same as the current user
		if (currentUser.getId() == selectedComment.getAuthor().getId()) {
			getMenuInflater().inflate(R.menu.comment_list_item, menu);
		} else {
			getMenuInflater().inflate(R.menu.comment_list_item_no_delete, menu);

		}

	}

	// ==============================================================================
	// {{ Initialization Methods

	private void initializeWorkerFragment() {

		FragmentManager fragmentManager = getFragmentManager();
		commentsWorkerFragment = (CommentsWorkerFragment) fragmentManager
		        .findFragmentByTag(CommentsWorkerFragment.TAG);

		if (commentsWorkerFragment == null) {
			commentsWorkerFragment = CommentsWorkerFragment.createInstance(getApplicationContext());
			fragmentManager.beginTransaction()
			        .add(commentsWorkerFragment, CommentsWorkerFragment.TAG).commit();
		}

	}

	private void initializeData() {

		Intent intent = getIntent();
		Bundle extras = intent.getExtras();

		currentUser = (User) extras.getSerializable(EXTRA_CURRENT_USER);
		currentDocumentId = extras.getInt(EXTRA_CURRENT_DOCUMENT_ID);

		commentsOnDisplay = commentsWorkerFragment.getDocumentComments(currentDocumentId);
	}

	private void registerBroadcastReceivers() {

		// @formatter:off
//		IntentFilter submitCommentBroadcastReceiverFilter = new IntentFilter();
//		
//		submitCommentBroadcastReceiverFilter.addAction(OutgoingCommentsSubmitService.ACTION_ON_COMMENT_SUBMITTED);
//		submitCommentBroadcastReceiverFilter.addAction(OutgoingCommentsSubmitService.ACTION_ON_SUBMIT_FAILED);
//		submitCommentBroadcastReceiverFilter.addCategory(Intent.CATEGORY_DEFAULT);
//
//		registerReceiver(submitCommentBroadcastReceiver, submitCommentBroadcastReceiverFilter);
//
//		IntentFilter deleteCommentBroadcastReceiverFilter = new IntentFilter();
//		
//		deleteCommentBroadcastReceiverFilter.addAction(DeleteCommentsMarkedForDeletionService.ACTION_ON_SERVICE_STARTED);
//		deleteCommentBroadcastReceiverFilter.addAction(DeleteCommentsMarkedForDeletionService.ACTION_ON_SERVICE_DONE);
//		deleteCommentBroadcastReceiverFilter.addCategory(Intent.CATEGORY_DEFAULT);
//		
//		registerReceiver(deleteCommentBroadcastReceiver, deleteCommentBroadcastReceiverFilter);
		// @formatter:on

	}

	// }}

	// ==============================================================================
	// {{ Service Methods

	private void startDeleteCommentsService() {

		// Intent deleteCommentsService = new Intent(CommentsActivity.this,
		// DeleteCommentsMarkedForDeletionService.class);
		// deleteCommentsService.putExtra(OutgoingCommentsSubmitService.EXTRA_CURRENT_USER,
		// currentUser);
		// startService(deleteCommentsService);

	}

	// }}

	// ==============================================================================
	// {{ Functional Methods

	private void deleteComment(Comment comment) {

		// Validate if the comment is the user's own comment
		if (comment.getAuthor().getId() != currentUser.getId()) {
			Toast.makeText(this, "You cannot delete this comment", Toast.LENGTH_LONG).show();
			return;
		}

		// Validate if the comment is still being processed
		if (comment.isCurrentlyBeingProcessed()) {
			Toast.makeText(this, "This comment is still being processed, try again later.",
			        Toast.LENGTH_LONG).show();
			return;
		}

		if (comment.isOutgoing() && !comment.isCurrentlyBeingProcessed()) {
			// Delete the comment in the database

			try {
				commentsWorkerFragment.deleteComment(comment.getId());
			} catch (CommentDeleteFailedException e) {
				Toast.makeText(CommentsActivity.this,
				        "Failed to delete comment: " + e.getMessage(), Toast.LENGTH_LONG).show();
			}

		} else if (!comment.isOutgoing()) {
			// Mark the comment for deletion then run the service for deleting comments
			try {
				commentsWorkerFragment.markCommentForDeletion(comment.getId());
				if (SessionManager.getApplicationInstance().getMode() == Mode.ONLINE) {
					startDeleteCommentsService();
				}
			} catch (CommentDeleteFailedException e) {
				Toast.makeText(CommentsActivity.this,
				        "Failed to delete comment: " + e.getMessage(), Toast.LENGTH_LONG).show();
			}

		}

		// Update the UI
		commentsViewFragment.removeComment(comment);

	}

	// }}

	@Override
	public void onSubmitCommentCommand(String commentText) {

		Comment comment = new Comment();
		comment.setAuthor(currentUser);
		comment.setText(commentText);
		comment.setDocumentId(currentDocumentId);
		comment.setCurrentlyBeingProcessed(true);

		// Give the comment a stub id using the current date and time
		comment.setPendingStubId(DateUtilities.getServerFormattedCurrentDate());

		Comment updatedComment = commentsWorkerFragment.saveCommentAsOutgoingComment(comment);

		// // Submit the comment
		// Comment updatedComment = startSubmitCommentService(comment);

		// Update the UI
		commentsViewFragment.addComment(updatedComment);

	}
}
